﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sinacor.Infra.UI.Exceptions;
using Sinacor.Infra.Common.Exceptions;
using Sinacor.Infra.Common.Validation;
using PSE.Framework.UI.Resources;

namespace Sinacor.Infra.UI.Common
{
    [Serializable]
    public class ErrorDetail
    {
        public ErrorDetail(int id)
        {
            _id = id;
        }

        public ErrorDetail(int id, string message)
            : this(id)
        {
            _message = message;
        }

        private int _id;
        public int Id
        {
            get { return _id; }
            set { _id = value; }
        }

        private string _message;
        public string Message
        {
            get { return _message; }
            set { _message = value; }
        }

        public static List<ErrorDetail> CreateFromException(Exception exception)
        {
            if (exception == null)
                throw new ArgumentNullException("exception");

            List<ErrorDetail> details = new List<ErrorDetail>();

            ErrorMessage.ConfigureExceptionMessage(exception);

            if (exception is ValidationException)
            {
                foreach (ValidationError validationError in ((ValidationException)exception).ValidationErrors.Values)
                {
                    details.Add(new ErrorDetail(validationError.GetHashCode(), validationError.ErrorMessage));
                }
            }
            else if (exception is BaseErrorNumberException)
            {
                object[] parameters = new object[0];

                if (exception is BusinessException)
                    parameters = ((BusinessException)exception).Parameters.ToArray();

                details.Add(new ErrorDetail(exception.GetHashCode(), exception.Message));
            }
            else
            {
                throw new ArgumentException("Invalid exception type, only BusinessException, ValidationException and LicensingException are allowed", "exception", exception);
            }

            return details;
        }

        public static ErrorDetail CreateFromResourceKey(string resourceKey, params object[] parameters)
        {
            if (string.IsNullOrEmpty(resourceKey))
                throw new ArgumentNullException("resourceKey");

            // Capturando provider de recursos
            IResourceProvider resourceProvider = ResourceProviderManager.GetResourceProvider();

            string message = (string)resourceProvider.TryGetResource(resourceKey, parameters);

            ErrorDetail errorDetail = new ErrorDetail(resourceKey.GetHashCode(), message);

            return errorDetail;
        }

        public static bool operator ==(ErrorDetail x, ErrorDetail y)
        {
            if (((object)x) != null && ((object)y) != null)
                return x.Id == y.Id;
            else
                return ((object)x) == null && ((object)y) == null;
        }

        public static bool operator !=(ErrorDetail x, ErrorDetail y)
        {
            return !(x == y);
        }

        public override bool Equals(object obj)
        {
            ErrorDetail e = obj as ErrorDetail;
            if (e != null)
                return this == e;
            else
                return false;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }
}
